// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library htmldoc.templates;

import 'dart:async' show Future;
import 'dart:io' show File;

import 'package:mustache4dart/mustache4dart.dart';

import 'resource_loader.dart' as loader;

typedef String TemplateRenderer(context,
    {bool assumeNullNonExistingProperty, bool errorOnMissingProperty});

/**
 * 将常用的组件单独封装为模板，如：header、footer、最新帖子、标签云、网站信息等
 * 现目前仅实现了 header 和 footer
 */
const _partials = const <String>[
  'footer',
  'header'
];

Future<Map<String, String>> _loadPartials(
    List<String> headerPaths, List<String> footerPaths) async {
  headerPaths ??= [];
  footerPaths ??= [];

  var partials = <String, String>{};

  Future<String> _loadPartial(String templatePath) async {
    String template = await _getTemplateFile(templatePath);
    if (templatePath.contains('_header') && headerPaths.isNotEmpty) {
      String headerValue = headerPaths
          .map((path) => new File(path).readAsStringSync())
          .join('\n');
      template =
          template.replaceAll('<!-- Header Placeholder -->', headerValue);
      template =
          template.replaceAll('  <!-- Do not remove placeholder -->\n', '');
    }
    if (templatePath.contains('_footer') && footerPaths.isNotEmpty) {
      String footerValue = footerPaths
          .map((path) => new File(path).readAsStringSync())
          .join('\n');
      template =
          template.replaceAll('<!-- Footer Placeholder -->', footerValue);
      template =
          template.replaceAll('  <!-- Do not remove placeholder -->\n', '');
    }
    return template;
  }

  for (String partial in _partials) {
    partials[partial] = await _loadPartial('_$partial.html');
  }

  return partials;
}

Future<String> _getTemplateFile(String templateFileName) =>
    loader.loadAsString('package:loyhd/templates/$templateFileName');

/**
 * 可渲染的模板，目前仅渲染 index ，
 * 后续添加 forum 、thread 、about 等等
 */
class Templates {
  final TemplateRenderer indexTemplate;

  static Future<Templates> create(
      {List<String> headerPaths, List<String> footerPaths}) async {
    var partials = await _loadPartials(headerPaths, footerPaths);

    String _partial(String name) {
      String partial = partials[name];
      if (partial == null || partial.isEmpty) {
        throw new StateError('Did not find partial "$name"');
      }
      return partial;
    }

    Future<TemplateRenderer> _loadTemplate(String templatePath) async {
      String templateContents = await _getTemplateFile(templatePath);
      return compile(templateContents, partial: _partial) as TemplateRenderer;
    }

    var indexTemplate = await _loadTemplate('index.html');

    return new Templates._(
        indexTemplate);
  }

  Templates._(
      this.indexTemplate,);
}
